/**************************************************************************//**
 * @item     CosyOS-II Kernel
 * @file     sv_task.c
 * @brief    任务服务
 * @details  仅在任务中调用并执行。
 * @author   迟凯峰
 * @version  V3.2.0
 * @date     2024.12.13
 ******************************************************************************/

#include "os_var.h"
#include "os_api.h"
#include "ur_api.h"

/**
 @addtogroup CosyOS_内核服务
 @{
 *//**
 \defgroup   任务服务
 \brief      仅在任务中调用并执行。
 @{
 */

/** 禁止调度（支持嵌套）*/
void su_forbid_schedule(void)
{
	s_sign_schedule_forbid = true;
	s_forbid_counter++;
}

/** 恢复调度（支持嵌套）*/
void su_resume_schedule(void)
{
	s_forbid_counter--;
	if(!s_forbid_counter){
		s_sign_schedule_forbid = false;
		if(s_sign_schedule && !s_taskcri_counter){
			mPendSV_Set;
		}
	}
}

/** 进入嵌套任务临界区 */
void su_enter_critical(void)
{
	mSysIRQ_Disable;
	s_taskcri_counter++;
}

/** 退出嵌套任务临界区 */
void su_exit_critical(void)
{
	s_taskcri_counter--;
	if(!s_taskcri_counter){
		if(s_sign_schedule && !s_sign_schedule_forbid){
			mPendSV_Set;
			mSysIRQ_Enable;
			#if MCUCFG_ISA == __ARM__
			OS_NOPx1;
			#endif
			while(s_sign_schedule);
		}
		else{
			mSysIRQ_Enable;
		}
	}
}

/** 退出嵌套任务临界区并返回(void *) */
void *su_return_voidptr(void *p)
{
	uExitCritical;
	return p;
}

/** 进入非嵌套任务临界区 */
void su_enter_critical_one(void)
{
	mSysIRQ_Disable;
}

/** 退出非嵌套任务临界区 */
void su_exit_critical_one(void)
{
	mSysIRQ_Enable;
}

/** 退出非嵌套任务临界区并触发任务调度 */
void su_exit_critical_psv(void)
{
	s_sign_schedule = true;
	mPendSV_Set;
	mSysIRQ_Enable;
	#if MCUCFG_ISA == __ARM__
	OS_NOPx1;
	#endif
	while(s_sign_schedule);
}

/** 退出非嵌套任务临界区并返回(void *)，邮箱、队列专用 */
#if SYSCFG_MAILBOX == __ENABLED__ || SYSCFG_MSGQUEUE == __ENABLED__
static void *_ret_vptr_(void *p)
{
	mSysIRQ_Enable;
	return p;
}
#endif



/*
 * 操作任务
 */

/**
 \brief      启动任务
 \param[in]  hhand     任务HAND句柄
 \param[in]  entry     任务函数入口
 \param[in]  status    任务初始状态
 \return     错误码 [0：无错误]
 */
s_ecode_t su_startup_task(s_taskhand_tsp hhand, s_voidvoid_tfp entry, s_u8_t status)
{
	static s_tid_t _SYS_MEM_ tid = 0;
	if(!hhand->tid){
		tid++;
		hhand->tid = tid;
	}
	s_task_status0 = status;
	if(entry != OS_NULL){
		hhand->entry = entry;
	}
	s_task_starter = hhand;
	su_exit_critical_psv();
	return s_startup_code;
}

/**
 \brief      挂起任务
 \param[in]  htask     任务句柄
 \return     错误码 [0：无错误]
 */
s_ecode_t su_suspend_task(s_tasknode_tsp htask)
{
	if(htask == OS_NULL){
		uExitCritical;
		return OS_ECODE_TASKNOTSTARTED;
	}
	if(htask->status < OS_STATUS_SUSPENDED){
		htask->status |= OS_STATUS_SUSPENDED;
		if(htask == s_task_current){
			s_sign_schedule = true;
		}
		uExitCritical;
		return OS_ECODE_NOERROR;
	}
	if(htask->status & OS_STATUS_SUSPENDED){
		uExitCritical;
		return OS_ECODE_TASKSUSPENDED;
	}
	if(htask->status & OS_STATUS_STOPPED){
		uExitCritical;
		return OS_ECODE_TASKSTOPPED;
	}
	if(htask->status == OS_STATUS_DELETED){
		uExitCritical;
		return OS_ECODE_TASKNOTSTARTED;
	}
	else{
		uExitCritical;
		return OS_ECODE_DONOTKNOW;
	}
}

/**
 \brief      恢复任务
 \param[in]  htask     任务句柄
 \return     错误码 [0：无错误]
 */
s_ecode_t su_resume_task(s_tasknode_tsp htask)
{
	if(htask == OS_NULL){
		uExitCritical;
		return OS_ECODE_TASKNOTSTARTED;
	}
	if(htask->status & OS_STATUS_SUSPENDED){
		htask->status &= (~OS_STATUS_SUSPENDED & 0xFF);
		s_switch_ready(htask);
		uExitCritical;
		return OS_ECODE_NOERROR;
	}
	if(htask->status < OS_STATUS_STOPPED){
		uExitCritical;
		return OS_ECODE_TASKNOTSUSPENDED;
	}
	if(htask->status & OS_STATUS_STOPPED){
		uExitCritical;
		return OS_ECODE_TASKSTOPPED;
	}
	if(htask->status == OS_STATUS_DELETED){
		uExitCritical;
		return OS_ECODE_TASKNOTSTARTED;
	}
	else{
		uExitCritical;
		return OS_ECODE_DONOTKNOW;
	}
}

/**
 \brief      恢复指定任务并挂起自身任务
 \param[in]  htask     任务句柄
 \return     错误码 [0：无错误]
 */
s_ecode_t su_resume_suspend(s_tasknode_tsp htask)
{
	if(htask == OS_NULL){
		uExitCritical;
		return OS_ECODE_TASKNOTSTARTED;
	}
	if(htask->status & OS_STATUS_SUSPENDED){
		htask->status &= (~OS_STATUS_SUSPENDED & 0xFF);
	}
	if(htask->status == OS_STATUS_READY){
		s_task_current->status |= OS_STATUS_SUSPENDED;
		s_switch_taskpri(htask);
		s_sign_schedule = true;
		uExitCritical;
		return OS_ECODE_NOERROR;
	}
	if(htask->status < OS_STATUS_STOPPED){
		uExitCritical;
		return OS_ECODE_TASKNOTREADY;
	}
	if(htask->status & OS_STATUS_STOPPED){
		uExitCritical;
		return OS_ECODE_TASKSTOPPED;
	}
	if(htask->status == OS_STATUS_DELETED){
		uExitCritical;
		return OS_ECODE_TASKNOTSTARTED;
	}
	else{
		uExitCritical;
		return OS_ECODE_DONOTKNOW;
	}
}

/**
 \brief      删除任务
 \param[in]  htask     任务句柄
 \return     错误码 [0：无错误]
 */
s_ecode_t su_delete_task(s_tasknode_tsp htask)
{
	if(htask == OS_NULL){
		uExitCritical;
		return OS_ECODE_TASKNOTSTARTED;
	}
	if(htask->status < OS_STATUS_DELETED){
		htask->status = OS_STATUS_DELETED;
		if(htask == s_task_current){
			s_sign_schedule = true;
		}
		uExitCritical;
		return OS_ECODE_NOERROR;
	}
	if(htask->status == OS_STATUS_DELETED){
		uExitCritical;
		return OS_ECODE_TASKNOTSTARTED;
	}
	else{
		uExitCritical;
		return OS_ECODE_DONOTKNOW;
	}
}

/**
 \brief      设置任务优先级
 \param[in]  htask     任务句柄
 \param[in]  pri       任务新优先级
 \return     错误码 [0：无错误]
 */
s_ecode_t su_set_taskpri(s_tasknode_tsp htask, s_u8_t pri)
{
	if(htask == OS_NULL){
		uExitCritical;
		return OS_ECODE_TASKNOTSTARTED;
	}
	if(htask->status < OS_STATUS_STOPPED){
		if(htask->pri != pri){
			htask->pri = pri;
			s_set_taskpri(htask);
			s_sign_schedule = true;
			uExitCritical;
			return OS_ECODE_NOERROR;
		}
		else{
			uExitCritical;
			return OS_ECODE_TASKPRIUNCHANGED;
		}
	}
	if(htask->status & OS_STATUS_STOPPED){
		uExitCritical;
		return OS_ECODE_TASKSTOPPED;
	}
	if(htask->status == OS_STATUS_DELETED){
		uExitCritical;
		return OS_ECODE_TASKNOTSTARTED;
	}
	else{
		uExitCritical;
		return OS_ECODE_DONOTKNOW;
	}
}

/**
 \brief      设置阻塞（时间）
 \param[in]  htask     任务句柄
 \param[in]  tick      阻塞时间 [单位：滴答周期，0：等效于清除阻塞，~0：无限阻塞]
 \return     错误码 [0：无错误]
 */
s_ecode_t su_set_block(s_tasknode_tsp htask, s_delay_t tick)
{
	if(htask == OS_NULL){
		uExitCritical;
		return OS_ECODE_TASKNOTSTARTED;
	}
	if(htask->status == OS_STATUS_BLOCKED || htask->status == OS_STATUS_FLOATING){
		if(!tick){
			htask->status = OS_STATUS_READY;
			s_switch_taskpri(htask);
		}
		htask->timer = tick;
		uExitCritical;
		return OS_ECODE_NOERROR;
	}
	else{
		uExitCritical;
		return OS_ECODE_TASKNOTBLOCKED;
	}
}

/**
 \brief      清除阻塞（状态）
 \param[in]  htask     任务句柄
 \return     错误码 [0：无错误]
 */
s_ecode_t su_clear_block(s_tasknode_tsp htask)
{
	if(htask == OS_NULL){
		uExitCritical;
		return OS_ECODE_TASKNOTSTARTED;
	}
	if(htask->status == OS_STATUS_BLOCKED || htask->status == OS_STATUS_FLOATING){
		htask->status = OS_STATUS_READY;
		htask->timer = 0;
		s_switch_taskpri(htask);
		uExitCritical;
		return OS_ECODE_NOERROR;
	}
	else{
		uExitCritical;
		return OS_ECODE_TASKNOTBLOCKED;
	}
}

/**
 \brief      自身任务延时（自动选择阻塞延时或就绪延时）
 \param[in]  tick      延时时间 [单位：滴答周期，~0：无限延时]
 \return     无
 */
void su_delay(s_delay_t tick)
{
	if(!s_sign_schedule_forbid){ /* 阻塞延时 */
		s_task_current->status = OS_STATUS_BLOCKED;
		s_task_current->timer = tick;
		su_exit_critical_psv();
	}
	else{ /* 就绪延时 */
		#if MCUCFG_ISA == __ARM__
		s_task_current->timer = tick;
		while(s_task_current->timer);
		#else
		mSysIRQ_Disable;
		s_task_current->timer = tick;
		do{
			mSysIRQ_Enable;
			while(s_task_current->timer);
			mSysIRQ_Disable;
		}while(s_task_current->timer);
		mSysIRQ_Enable;
		#endif
	}
}

/**
 \brief      切换任务
 \param[in]  htask     任务句柄
 \return     无
 */
void su_switch_task(s_tasknode_tsp htask)
{
	if(htask != OS_NULL && htask->status < OS_STATUS_STOPPED){
		s_switch_taskpri(htask);
	}
	uExitCritical;
}

/**
 \brief      禅让任务
 \param      无
 \return     无
 */
void su_yield_tasking(void)
{
	uEnterCritical;
	s_tick_counter = ~0;
	s_sign_schedule = true;
	uExitCritical;
}



/*
 * 互斥信号量
 */
#if SYSCFG_MUTEX == __ENABLED__
/**
 \brief      获取互斥信号量
 \param[in]  hmut      互斥信号量句柄
 \param[in]  tick      超时时间 [单位：滴答周期，0：立即返回，~0：无限等待]
 \return     结果 [true：成功，false：失败]
 */
s_bool_t su_take_mutex(s_mutex_tsp hmut, s_delay_t tick)
{
	if(!hmut->mutex) goto __RET_TRUE1;
	if(s_task_current == hmut->htask) goto __RET_TRUE2;
	if(!tick) goto __RET_FALSE;
	
	s_task_current->status = OS_STATUS_BLOCKED;
	s_task_current->blocktype = OS_BLOCKED_MUTEX | 0x0F;
	s_task_current->timer = tick;
	s_task_current->handle = hmut;
	if(s_task_current->pri > hmut->htask->pri){
		hmut->htask->pri = s_task_current->pri;
		s_set_taskpri(hmut->htask);
	}
	su_exit_critical_psv();
	s_task_current->blocktype = 0;
	#if SYSCFG_MCUCORE == 8051
	hmut = (s_mutex_tsp)s_task_current->handle;
	#endif
	if(!hmut->mutex) goto __RET_TRUE1;
	
__RET_FALSE:
	mSysIRQ_Enable;
	return false;
	
__RET_TRUE1:
	hmut->htask = s_task_current;
	hmut->oldpri = s_task_current->pri;
	
__RET_TRUE2:
	hmut->mutex++;
	mSysIRQ_Enable;
	return true;
}

/**
 \brief      归还互斥信号量
 \param[in]  hmut      互斥信号量句柄
 \return     无
 */
void su_back_mutex(s_mutex_tsp hmut)
{
	if(!hmut->mutex);
	else if(s_task_current == hmut->htask){
		hmut->mutex--;
		if(!hmut->mutex){
			if(s_task_current->pri > hmut->oldpri){
				s_task_current->pri = hmut->oldpri;
				s_set_taskpri(s_task_current);
				s_sign_schedule = true;
			}
		}
	}
	uExitCritical;
}
#endif



/*
 * 二值信号量
 */
#if SYSCFG_BINARY == __ENABLED__
/**
 \brief      等待二值信号量
 \param[in]  hbin      二值信号量句柄
 \param[in]  tick      超时时间 [单位：滴答周期，0：立即返回，~0：无限等待]
 \return     结果 [true：成功，false：失败]
 */
s_bool_t su_wait_binary(s_binary_tsp hbin, s_delay_t tick)
{
	if(hbin->binary) goto __RET_TRUE;
	if(!tick) goto __RET_FALSE;
	
	hbin->htask = s_task_current;
	s_task_current->status = OS_STATUS_BLOCKED;
	s_task_current->blocktype = OS_BLOCKED_BINARY | sizeof(hbin->binary);
	s_task_current->timer = tick;
	s_task_current->handle = hbin;
	su_exit_critical_psv();
	s_task_current->blocktype = 0;
	#if SYSCFG_MCUCORE == 8051
	hbin = (s_binary_tsp)s_task_current->handle;
	#endif
	hbin->htask = OS_NULL;
	if(hbin->binary) goto __RET_TRUE;
	
__RET_FALSE:
	mSysIRQ_Enable;
	return false;
	
__RET_TRUE:
	mSysIRQ_Enable;
	return true;
}

/**
 \brief      获取二值信号量
 \param[in]  hbin      二值信号量句柄
 \param[in]  tick      超时时间 [单位：滴答周期，0：立即返回，~0：无限等待]
 \return     结果 [true：成功，false：失败]
 */
s_bool_t su_take_binary(s_binary_tsp hbin, s_delay_t tick)
{
	if(hbin->binary) goto __RET_TRUE;
	if(!tick) goto __RET_FALSE;
	
	if(hbin->htask == OS_NULL || s_task_current->pri > hbin->htask->pri){
		hbin->htask = s_task_current;
	}
	s_task_current->status = OS_STATUS_BLOCKED;
	s_task_current->blocktype = OS_BLOCKED_BINARY | sizeof(hbin->binary);
	s_task_current->timer = tick;
	s_task_current->handle = hbin;
	su_exit_critical_psv();
	s_task_current->blocktype = 0;
	#if SYSCFG_MCUCORE == 8051
	hbin = (s_binary_tsp)s_task_current->handle;
	#endif
	hbin->htask = OS_NULL;
	if(hbin->binary) goto __RET_TRUE;
	
__RET_FALSE:
	mSysIRQ_Enable;
	return false;
	
__RET_TRUE:
	hbin->binary = false;
	mSysIRQ_Enable;
	return true;
}

/**
 \brief      给予二值信号量
 \param[in]  hbin      二值信号量句柄
 \return     无
 */
void su_give_binary(s_binary_tsp hbin)
{
	hbin->binary = true;
	s_switch_notnull(hbin->htask);
	uExitCritical;
}
#endif



/*
 * 计数信号量
 */
#if SYSCFG_SEMAPHORE == __ENABLED__
/**
 \brief      获取计数信号量
 \param[in]  hsem      计数信号量句柄
 \param[in]  tick      超时时间 [单位：滴答周期，0：立即返回，~0：无限等待]
 \return     结果 [true：成功，false：失败]
 */
s_bool_t su_take_semaphore(s_semaph_tsp hsem, s_delay_t tick)
{
	if(hsem->counter) goto __RET_TRUE;
	if(!tick) goto __RET_FALSE;
	
	if(hsem->htask == OS_NULL || s_task_current->pri > hsem->htask->pri){
		hsem->htask = s_task_current;
	}
	s_task_current->status = OS_STATUS_BLOCKED;
	s_task_current->blocktype = OS_BLOCKED_SEMAPHORE | sizeof(hsem->counter);
	s_task_current->timer = tick;
	s_task_current->handle = hsem;
	su_exit_critical_psv();
	s_task_current->blocktype = 0;
	#if SYSCFG_MCUCORE == 8051
	hsem = (s_semaph_tsp)s_task_current->handle;
	#endif
	hsem->htask = OS_NULL;
	if(hsem->counter) goto __RET_TRUE;
	
__RET_FALSE:
	mSysIRQ_Enable;
	return false;
	
__RET_TRUE:
	(hsem->counter)--;
	mSysIRQ_Enable;
	return true;
}

/**
 \brief      给予计数信号量
 \param[in]  hsem      计数信号量句柄
 \return     无
 */
void su_give_semaphore(s_semaph_tsp hsem)
{
	if(hsem->counter < hsem->maximum){
		hsem->counter++;
	}
	s_switch_notnull(hsem->htask);
	uExitCritical;
}
#endif



/*
 * 私信
 */
#if SYSCFG_TASKMSG == __ENABLED__
/**
 \brief      接收私信
 \param[in]  flag      私信标志，有新私信时，该标志为真
 \param[in]  tick      超时时间 [单位：滴答周期，0：立即返回，~0：无限等待]
 \return     结果 [true：成功，false：失败]
 */
s_bool_t su_recv_taskmsg(m_taskmsg_t _STATIC_MEM_ *flag, s_delay_t tick)
{
	if(*flag) goto __RET_TRUE;
	if(!tick) goto __RET_FALSE;
	
	s_task_current->status = OS_STATUS_BLOCKED;
	s_task_current->blocktype = OS_BLOCKED_TASKMSG | sizeof(*flag);
	s_task_current->timer = tick;
	s_task_current->handle = flag;
	su_exit_critical_psv();
	s_task_current->blocktype = 0;
	#if SYSCFG_MCUCORE == 8051
	flag = (m_taskmsg_t *)s_task_current->handle;
	#endif
	if(*flag) goto __RET_TRUE;
	
__RET_FALSE:
	mSysIRQ_Enable;
	return false;
	
__RET_TRUE:
	*flag = false;
	return true;
}
#endif



/* 
 * 飞信
 */
#if SYSCFG_FETION == __ENABLED__
/**
 \brief      接收飞信
 \param[in]  htbox     信箱句柄
 \return     飞信数据 [false：失败]
 */
static m_fetion_t _recv_fetion_(s_tionbox_tsp htbox)
{
	m_fetion_t fetion = htbox->fetion;
	htbox->fetion = false;
	mSysIRQ_Enable;
	return fetion;
}

/**
 \brief      接收飞信
 \param[in]  htbox     信箱句柄
 \param[in]  tick      超时时间 [单位：滴答周期，0：立即返回，~0：无限等待]
 \return     飞信数据 [false：失败]
 */
m_fetion_t su_recv_fetion(s_tionbox_tsp htbox, s_delay_t tick)
{
	if(htbox->fetion) goto __RET_TION;
	if(!tick) goto __RET_FALSE;
	
	htbox->htask = s_task_current;
	s_task_current->status = OS_STATUS_BLOCKED;
	s_task_current->blocktype = OS_BLOCKED_FETION | sizeof(htbox->fetion);
	s_task_current->timer = tick;
	s_task_current->handle = htbox;
	su_exit_critical_psv();
	s_task_current->blocktype = 0;
	#if SYSCFG_MCUCORE == 8051
	htbox = (s_tionbox_tsp)s_task_current->handle;
	#endif
	htbox->htask = OS_NULL;
	
__RET_TION:
	return _recv_fetion_(htbox);
	
__RET_FALSE:
	mSysIRQ_Enable;
	return false;
}
#endif



/*
 * 邮箱
 */
#if SYSCFG_MAILBOX == __ENABLED__
/**
 \brief      接收邮件
 \param[in]  hmbox     邮箱句柄
 \param[in]  tick      超时时间 [单位：滴答周期，0：立即返回，~0：无限等待]
 \return     邮件指针 [NULL：失败]
 */
void *su_recv_mail(s_mailbox_tsp hmbox, s_delay_t tick)
{
	if(hmbox->flag) goto __RET_MAIL;
	if(!tick) goto __RET_NULL;
	
	hmbox->htask = s_task_current;
	s_task_current->status = OS_STATUS_BLOCKED;
	s_task_current->blocktype = OS_BLOCKED_MAIL | sizeof(hmbox->flag);
	s_task_current->timer = tick;
	s_task_current->handle = hmbox;
	su_exit_critical_psv();
	s_task_current->blocktype = 0;
	#if SYSCFG_MCUCORE == 8051
	hmbox = (s_mailbox_tsp)s_task_current->handle;
	#endif
	hmbox->htask = OS_NULL;
	if(hmbox->flag) goto __RET_MAIL;
	
__RET_NULL:
	mSysIRQ_Enable;
	return OS_NULL;
	
__RET_MAIL:
	hmbox->flag = false;
	return _ret_vptr_(hmbox->mail);
}

/**
 \brief      发送邮件
 \param[in]  hmbox     邮箱句柄
 \param[in]  mail      邮件指针
 \return     无
 */
void su_send_mail(s_mailbox_tsp hmbox, void *mail)
{
	hmbox->flag = false;
	hmbox->mail = mail;
	hmbox->flag = true;
	s_switch_notnull(hmbox->htask);
	uExitCritical;
}
#endif



/*
 * 消息队列
 */
#if SYSCFG_MSGQUEUE == __ENABLED__
/**
 \brief      接收消息
 \param[in]  hque      队列句柄
 \param[in]  tick      超时时间 [单位：滴答周期，0：立即返回，~0：无限等待]
 \return     消息指针 [NULL：失败]
 */
void *su_recv_msg(s_queue_tsp hque, s_delay_t tick)
{
	void *msg;
	s_msgnode_tsp hmsg;
	hque->mutex = false;
	
	if(hque->counter) goto __RECV_MSG;
	if(!tick) goto __RET_NULL;
	
	hque->mutex = true;
	hque->htask = s_task_current;
	s_task_current->status = OS_STATUS_BLOCKED;
	s_task_current->blocktype = OS_BLOCKED_MSG | sizeof(hque->counter);
	s_task_current->timer = tick;
	s_task_current->handle = hque;
	su_exit_critical_psv();
	s_task_current->blocktype = 0;
	#if SYSCFG_MCUCORE == 8051
	hque = (s_queue_tsp)s_task_current->handle;
	#endif
	hque->htask = OS_NULL;
	hque->mutex = false;
	if(!hque->counter) goto __RET_NULL;
	
__RECV_MSG:
	if(hque->type == __DYNAMIC__)
		sRecvMsg_Dynamic(msg);
	else
		sRecvMsg_Static(msg);
	hque->mutex = true;
	return _ret_vptr_(msg);
	
__RET_NULL:
	hque->mutex = true;
	mSysIRQ_Enable;
	return OS_NULL;
}

/**
 \brief      发送消息
 \param[in]  hque      队列句柄
 \param[in]  msg       消息指针
 \return     错误码 [0：无错误]
 */
s_ecode_t su_send_msg(s_queue_tsp hque, void *msg)
{
	hque->mutex = false;
	
	if(hque->counter == hque->len){
		#if SYSCFG_DEBUGGING == __ENABLED__
		s_alarm.overflow_msgqueue = true;
		#endif
		hque->mutex = true;
		uExitCritical;
		return OS_ECODE_OVERFLOW_MSGQUEUE;
	}
	if(hque->type == __DYNAMIC__){
		s_msgnode_tsp hmsg = OS_NULL;
		hmsg = (s_msgnode_tsp)s_malloc(sizeof(s_msgnode_ts));
		if(hmsg == OS_NULL){
			#if SYSCFG_DEBUGGING == __ENABLED__
			s_fault.mallocfailed_msgnode = true;
			#endif
			hque->mutex = true;
			uExitCritical;
			return OS_ECODE_MALLOCFAIL_MSGNODE;
		}
		sSendMsg_Dynamic(msg);
	}
	else
		sSendMsg_Static(msg);
	
	s_switch_notnull(hque->htask);
	hque->mutex = true;
	uExitCritical;
	return OS_ECODE_NOERROR;
}
#endif



/*
 * 事件标志组
 */
#if SYSCFG_FLAGGROUP == __ENABLED__
/**
 \brief      查询标志组
 \param[in]  hgrp      标志组句柄
 \param[in]  size      sizeof(group)
 \return     结果 [true：成功，false：失败]
 */
s_bool_t su_query_group(void _STATIC_MEM_ *hgrp, s_u8_t size)
{
	switch(size){
	case 1: if(*(s_u8_t  *)hgrp) goto __RET_TRUE; break;
	case 2: if(*(s_u16_t *)hgrp) goto __RET_TRUE; break;
	case 4: if(*(s_u32_t *)hgrp) goto __RET_TRUE; break;
	}
	uExitCritical;
	return false;
	
__RET_TRUE:
	uExitCritical;
	return true;
}

/**
 \brief      等待标志组
 \param[in]  hgrp      标志组句柄
 \param[in]  size      sizeof(group)
 \param[in]  tick      超时时间 [单位：滴答周期，0：立即返回，~0：无限等待]
 \return     结果 [true：成功，false：失败]
 */
s_bool_t su_wait_group(void _STATIC_MEM_ *hgrp, s_u8_t size, s_delay_t tick)
{
	switch(size){
	case 1: if(*(s_u8_t  *)hgrp) goto __RET_TRUE; break;
	case 2: if(*(s_u16_t *)hgrp) goto __RET_TRUE; break;
	case 4: if(*(s_u32_t *)hgrp) goto __RET_TRUE; break;
	}
	if(!tick) goto __RET_FALSE;
	
	s_task_current->status = OS_STATUS_BLOCKED;
	s_task_current->blocktype = OS_BLOCKED_FLAGGROUP | size;
	s_task_current->timer = tick;
	s_task_current->handle = hgrp;
	su_exit_critical_psv();
	#if SYSCFG_MCUCORE == 8051 || SYSCFG_MCUCORE == 80251
	size = s_task_current->blocktype & 0x0F;
	#endif
	s_task_current->blocktype = 0;
	#if SYSCFG_MCUCORE == 8051
	hgrp = s_task_current->handle;
	#endif
	switch(size){
	case 1: if(*(s_u8_t  *)hgrp) goto __RET_TRUE; break;
	case 2: if(*(s_u16_t *)hgrp) goto __RET_TRUE; break;
	case 4: if(*(s_u32_t *)hgrp) goto __RET_TRUE; break;
	}
__RET_FALSE:
	mSysIRQ_Enable;
	return false;
	
__RET_TRUE:
	mSysIRQ_Enable;
	return true;
}
#endif



/*
 * 动态内存
 */
#if SYSCFG_DYNMEMMGE == __ENABLED__
/**
 \brief      uxalloc
 \param[in]  p         
 \return     指针 [NULL：失败]
 */
void _MALLOC_MEM_ *su_xalloc(void _MALLOC_MEM_ *p)
{
	uExitCritical;
	return p;
}

/**
 \brief      初始化线程内存池
 \param[in]  hmem      线程内存句柄
 \param[in]  size      内存池大小
 \return     结果 [true：成功，false：失败]
 */
s_bool_t su_init_mempool(s_thrmem_tsp hmem, size_t size)
{
	hmem->head = hmem->move = (void _MALLOC_MEM_ *)s_malloc(size);
	if(hmem->head == OS_NULL){
		uExitCritical;
		return false;
	}
	else{
		hmem->size = size;
		uExitCritical;
		return true;
	}
}

/**
 \brief      线程内存分配
 \param[in]  hmem      线程内存句柄
 \param[in]  size      内存块大小
 \return     指针 [NULL：分配失败]
 */
void _MALLOC_MEM_ *su_talloc(s_thrmem_tsp hmem, size_t size)
{
	if(hmem->head == OS_NULL || (size_t)hmem->move - (size_t)hmem->head + size > hmem->size){
		return OS_NULL;
	}
	else{
		void _MALLOC_MEM_ *r = hmem->move;
		hmem->move = (s_u8_t _MALLOC_MEM_ *)hmem->move + size;
		return r;
	}
}
#endif

/** @} */
/** @} */
